/////////////////////////////////////////////////////////////////
/// @file mdp_dynalloc.h
/// @version 2009-12-21
/// @author Massimo Di Pierro <mdipierro@cs.depaul.edu>
///
/// Declaration of overloaded new and delete operators 
/// to use memalign when compiled with #define SSE2
/// Required for SSE/SSE2 assembly macros
///
/// Licensed under GPL2 license
/// Read attached license in file mdp_license.pdf
/// This file cannot be distributed without file mdp_license.pdf
//////////////////////////////////////////////////////////////////

#ifndef OSX
#include "malloc.h"
#endif

#ifdef MEMOPTIMIZE
/// the MEMOPTIMIZE option is not fully tested because of a bug in map<void*,...>
map<size_t,deque<void*> > __stored;
map<void*,size_t> __stored_size;
#endif

void* operator new(size_t size) {
#if !defined(SSE2) || defined(OSX)
  void *p=malloc(size);
#else
  void *p=memalign(64,size);
#endif
  return p;
}

void operator delete (void* pointer) {
  free(pointer); 
}

void* operator new[] (size_t size) {
#if !defined(SSE2) || defined(OSX)
  void* p;
#ifdef MEMOPTIMIZE  
  map<size_t,deque<void*> >::iterator q=__stored.find(size);
  if(q!=__stored.end() && q->second.size()) {p=q->second[0]; q->second.pop_front(); } else
#endif
   p=malloc(size);
#else
  p=memalign(64,size);
#endif
#ifdef MEMOPTIMIZE
  __stored_size[p]=size;
#endif
  return p;
}

void operator delete[] (void* pointer) {
#ifdef MEMOPTIMIZE
  __stored[__stored_size[pointer]].push_back(pointer);
#else
  free(pointer); 
#endif
}

